package com.guomei.service.pay;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.guomei.bean.PayRequest;
import com.guomei.bean.curse.CourseClassAssociation;
import com.guomei.bean.curse.CourseOrder;
import com.guomei.bean.curse.PayResponse;
import com.guomei.bean.curse.domain.UserCourseJoin;
import com.guomei.configs.WechatPayConfig;
import com.guomei.constans.RedisConstants;
import com.guomei.constans.ResultCode;
import com.guomei.service.curse.CourseClassAssociationService;
import com.guomei.service.curse.CourseOrderService;
import com.guomei.service.exam.ExamEnrollService;
import com.guomei.mapper.curse.UserCourseJoinMapper;
import com.guomei.utils.RedisUtils;
import com.guomei.utils.Result;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import javax.crypto.Cipher;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.SecretKeySpec;

@Service
@RequiredArgsConstructor
@Slf4j
public class WechatPayService implements PaymentService {

    private final WechatPayConfig wechatPayConfig;
    private final CloseableHttpClient wechatPayClient;
    private final CourseOrderService courseOrderService;
    private final CourseClassAssociationService courseClassAssociationService;
    private final ExamEnrollService examEnrollService;
    private final RedisUtils redisUtils;
    private final UserCourseJoinMapper userCourseJoinMapper;

    @Override
    public Result<?> createPayment(PayRequest request) throws AlipayApiException, IOException {
        try {
            log.info("创建微信支付订单: payType={}, scene={}, outTradeNo={}, totalAmount={}", 
                    request.getPayType(), request.getScene(), request.getOutTradeNo(), request.getTotalAmount());
            
            // 验证必需参数
            if (request.getTotalAmount() == null || request.getTotalAmount().compareTo(BigDecimal.ZERO) <= 0) {
                return Result.fail("支付金额必须大于0");
            }
            
            // 金额转换为分
            int totalFee = request.getTotalAmount().multiply(new BigDecimal("100")).intValue();
            
            PayResponse payResponse = new PayResponse();
            payResponse.setPayType("wechat");
            payResponse.setScene(request.getScene());
            payResponse.setOutTradeNo(request.getOutTradeNo());
            
            // 根据支付场景创建不同类型的支付
            switch (request.getScene().toLowerCase()) {
                case "native":
                    return createNativePay(request, totalFee, payResponse);
                case "h5":
                    return createH5Pay(request, totalFee, payResponse);
                case "jsapi":
                    return createJsapiPay(request, totalFee, payResponse);
                default:
                    return Result.fail("不支持的微信支付场景: " + request.getScene());
            }
        } catch (Exception e) {
            log.error("微信支付创建订单异常", e);
            return Result.fail("微信支付创建订单异常: " + e.getMessage());
        }
    }

    /**
     * Native 支付（扫码支付）
     */
    private Result<?> createNativePay(PayRequest request, int totalFee, PayResponse payResponse) {
        try {

            // 构建请求参数
            JSONObject requestBody = new JSONObject();

            requestBody.put("appid", wechatPayConfig.getAppId());

            requestBody.put("mchid", wechatPayConfig.getMchId());
            requestBody.put("description", request.getSubject());
            requestBody.put("out_trade_no", request.getOutTradeNo());
            requestBody.put("notify_url", wechatPayConfig.getNotifyUrl());
            
            // 金额信息
            JSONObject amount = new JSONObject();
            amount.put("total", totalFee);
            amount.put("currency", "CNY");
            requestBody.put("amount", amount);
            
            // 创建HTTP请求
            HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/pay/transactions/native");
            httpPost.setHeader("Content-Type", "application/json");
            httpPost.setHeader("Accept", "application/json");
            httpPost.setEntity(new StringEntity(requestBody.toJSONString(), "UTF-8"));
            
            // 发送请求
            try (CloseableHttpResponse response = wechatPayClient.execute(httpPost)) {
                HttpEntity entity = response.getEntity();
                String responseBody = EntityUtils.toString(entity, "UTF-8");
                
                log.info("微信Native支付API响应: status={}, body={}", response.getStatusLine().getStatusCode(), responseBody);
                
                if (response.getStatusLine().getStatusCode() == 200) {
                    JSONObject responseJson = JSON.parseObject(responseBody);
                    String codeUrl = responseJson.getString("code_url");
                    String prepayId = responseJson.getString("prepay_id");
                    
                    // 根据订单类型更新相应的微信交易号字段
                    if (codeUrl != null && !codeUrl.trim().isEmpty()) {
                        boolean updateResult = false;
                        if (isExamOrder(request.getOutTradeNo())) {
                            // 考试订单：更新考试报名记录的微信交易号
                            updateResult = examEnrollService.updateWxNoByOrderNo(request.getOutTradeNo(), codeUrl);
                        } else {
                            // 课程订单：更新课程订单记录的微信交易号
                            updateResult = courseOrderService.updateWxNoByOrderNo(request.getOutTradeNo(), codeUrl);
                        }
                        
                        if (updateResult) {
                            log.info("成功更新订单微信交易号: orderNo={}, codeUrl={}", request.getOutTradeNo(), codeUrl);
                        } else {
                            log.warn("更新订单微信交易号失败: orderNo={}, codeUrl={}", request.getOutTradeNo(), codeUrl);
                        }
                    }
                    
                    Map<String, Object> payParams = new HashMap<>();
                    payParams.put("code_url", codeUrl);
                    payParams.put("prepay_id", prepayId);
                    payParams.put("mchId", wechatPayConfig.getMchId());
                    payParams.put("outTradeNo", request.getOutTradeNo());
                    payParams.put("totalFee", totalFee);
                    payParams.put("description", request.getSubject());
                    payParams.put("notifyUrl", wechatPayConfig.getNotifyUrl());
                    
                    payResponse.setPayParams(payParams);
                    
                    log.info("微信Native支付创建成功: code_url={}, prepay_id={}", codeUrl, prepayId);
                    return Result.success(payResponse);
                } else {
                    log.error("微信Native支付API调用失败: status={}, response={}", 
                            response.getStatusLine().getStatusCode(), responseBody);
                    return Result.fail("微信支付创建失败: " + responseBody);
                }
            }
        } catch (Exception e) {
            log.error("微信Native支付创建失败", e);
            return Result.fail("微信Native支付创建失败: " + e.getMessage());
        }
    }

    /**
     * H5 支付
     */
    private Result<?> createH5Pay(PayRequest request, int totalFee, PayResponse payResponse) {
        try {
           
            // 构建请求参数
            JSONObject requestBody = new JSONObject();
            requestBody.put("appid", wechatPayConfig.getAppId());
            requestBody.put("mchid", wechatPayConfig.getMchId());
            requestBody.put("description", request.getSubject());
            requestBody.put("out_trade_no", request.getOutTradeNo());
            requestBody.put("notify_url", wechatPayConfig.getNotifyUrl());
            
            // 金额信息
            JSONObject amount = new JSONObject();
            amount.put("total", totalFee);
            amount.put("currency", "CNY");
            requestBody.put("amount", amount);
            
            // H5场景信息
            JSONObject sceneInfo = new JSONObject();
            JSONObject h5Info = new JSONObject();
            h5Info.put("type", "Wap");
            sceneInfo.put("h5_info", h5Info);
            requestBody.put("scene_info", sceneInfo);
            
            // 创建HTTP请求
            HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/pay/transactions/h5");
            httpPost.setHeader("Content-Type", "application/json");
            httpPost.setHeader("Accept", "application/json");
            httpPost.setEntity(new StringEntity(requestBody.toJSONString(), "UTF-8"));
            
            // 发送请求
            try (CloseableHttpResponse response = wechatPayClient.execute(httpPost)) {
                HttpEntity entity = response.getEntity();
                String responseBody = EntityUtils.toString(entity, "UTF-8");
                
                log.info("微信H5支付API响应: status={}, body={}", response.getStatusLine().getStatusCode(), responseBody);
                
                if (response.getStatusLine().getStatusCode() == 200) {
                    JSONObject responseJson = JSON.parseObject(responseBody);
                    String h5Url = responseJson.getString("h5_url");
                    String prepayId = responseJson.getString("prepay_id");
                    
                    Map<String, Object> payParams = new HashMap<>();
                    payParams.put("h5_url", h5Url);
                    payParams.put("prepay_id", prepayId);
                    payParams.put("mchId", wechatPayConfig.getMchId());
                    payParams.put("outTradeNo", request.getOutTradeNo());
                    payParams.put("totalFee", totalFee);
                    payParams.put("description", request.getSubject());
                    payParams.put("notifyUrl", wechatPayConfig.getNotifyUrl());
                    
                    payResponse.setPayParams(payParams);
                    
                    log.info("微信H5支付创建成功: h5_url={}, prepay_id={}", h5Url, prepayId);
                    return Result.success(payResponse);
                } else {
                    log.error("微信H5支付API调用失败: status={}, response={}", 
                            response.getStatusLine().getStatusCode(), responseBody);
                    return Result.fail("微信H5支付创建失败: " + responseBody);
                }
            }
        } catch (Exception e) {
            log.error("微信H5支付创建失败", e);
            return Result.fail("微信H5支付创建失败: " + e.getMessage());
        }
    }

    /**
     * JSAPI 支付（公众号支付）
     */
    private Result<?> createJsapiPay(PayRequest request, int totalFee, PayResponse payResponse) {
        try {
            if (request.getOpenId() == null || request.getOpenId().trim().isEmpty()) {
                return Result.fail("JSAPI支付需要提供用户openid");
            }
            
            // 构建请求参数
            JSONObject requestBody = new JSONObject();
            requestBody.put("appid", wechatPayConfig.getAppId());
            requestBody.put("mchid", wechatPayConfig.getMchId());
            requestBody.put("description", request.getSubject());
            requestBody.put("out_trade_no", request.getOutTradeNo());
            requestBody.put("notify_url", wechatPayConfig.getNotifyUrl());
            requestBody.put("payer", JSON.parseObject("{\"openid\":\"" + request.getOpenId() + "\"}"));
            
            // 金额信息
            JSONObject amount = new JSONObject();
            amount.put("total", totalFee);
            amount.put("currency", "CNY");
            requestBody.put("amount", amount);
            
            // 创建HTTP请求
            HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi");
            httpPost.setHeader("Content-Type", "application/json");
            httpPost.setHeader("Accept", "application/json");
            httpPost.setEntity(new StringEntity(requestBody.toJSONString(), "UTF-8"));
            
            // 发送请求
            try (CloseableHttpResponse response = wechatPayClient.execute(httpPost)) {
                HttpEntity entity = response.getEntity();
                String responseBody = EntityUtils.toString(entity, "UTF-8");
                
                log.info("微信JSAPI支付API响应: status={}, body={}", response.getStatusLine().getStatusCode(), responseBody);
                
                if (response.getStatusLine().getStatusCode() == 200) {
                    JSONObject responseJson = JSON.parseObject(responseBody);
                    String prepayId = responseJson.getString("prepay_id");
                    
                    Map<String, Object> payParams = new HashMap<>();
                    payParams.put("prepay_id", prepayId);
                    payParams.put("mchId", wechatPayConfig.getMchId());
                    payParams.put("openId", request.getOpenId());
                    payParams.put("outTradeNo", request.getOutTradeNo());
                    payParams.put("totalFee", totalFee);
                    payParams.put("description", request.getSubject());
                    payParams.put("notifyUrl", wechatPayConfig.getNotifyUrl());
                    
                    payResponse.setPayParams(payParams);
                    
                    log.info("微信JSAPI支付创建成功: prepay_id={}", prepayId);
                    return Result.success(payResponse);
                } else {
                    log.error("微信JSAPI支付API调用失败: status={}, response={}", 
                            response.getStatusLine().getStatusCode(), responseBody);
                    return Result.fail("微信JSAPI支付创建失败: " + responseBody);
                }
            }
        } catch (Exception e) {
            log.error("微信JSAPI支付创建失败", e);
            return Result.fail("微信JSAPI支付创建失败: " + e.getMessage());
        }
    }

    @Override
    public boolean handlePaymentNotify(String notifyData) {
        try {
            log.info("处理微信支付异步通知: {}", notifyData);
            
            // 解析通知数据
            JSONObject notifyJson = JSON.parseObject(notifyData);
            log.info("解析到的通知数据: {}", notifyJson);
            
            // 检查事件类型
            String eventType = notifyJson.getString("event_type");
            if (!"TRANSACTION.SUCCESS".equals(eventType)) {
                log.warn("非支付成功事件，跳过处理: {}", eventType);
                return true;
            }
            
            // 解密资源数据
            JSONObject resource = notifyJson.getJSONObject("resource");
            String ciphertext = resource.getString("ciphertext");
            String nonce = resource.getString("nonce");
            String associatedData = resource.getString("associated_data");
            
            // 解密支付结果数据
            String decryptedData = decryptResource(ciphertext, nonce, associatedData);
            if (decryptedData == null) {
                log.error("解密支付结果数据失败");
                return false;
            }
            
            log.info("解密后的支付结果: {}", decryptedData);
            
            // 解析支付结果
            JSONObject paymentResult = JSON.parseObject(decryptedData);
            String outTradeNo = paymentResult.getString("out_trade_no");
            String transactionId = paymentResult.getString("transaction_id");
            String tradeState = paymentResult.getString("trade_state");
            String successTime = paymentResult.getString("success_time");
            
            // 检查支付状态
            if (!"SUCCESS".equals(tradeState)) {
                log.warn("支付状态非成功: orderNo={}, tradeState={}", outTradeNo, tradeState);
                return true;
            }
            
            // 解析支付时间
            LocalDateTime payTime = null;
            if (successTime != null && !successTime.trim().isEmpty()) {
                try {
                    // 微信时间格式: 2025-09-13T20:42:39+08:00
                    payTime = LocalDateTime.parse(successTime.substring(0, 19), DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss"));
                } catch (Exception e) {
                    log.warn("解析支付时间失败: {}", successTime, e);
                    payTime = LocalDateTime.now();
                }
            } else {
                payTime = LocalDateTime.now();
            }
            
            // 根据订单号判断订单类型并更新状态
            boolean updateResult = false;
            if (isExamOrder(outTradeNo)) {
                // 考试报名订单支付处理
                updateResult = examEnrollService.updatePaymentStatus(outTradeNo, (short) 1, (short) 2, null, transactionId);
                if (updateResult) {
                    log.info("考试报名微信支付成功，订单状态更新成功: orderNo={}, transactionId={}, payTime={}", 
                            outTradeNo, transactionId, payTime);
                } else {
                    log.error("更新考试报名微信支付状态失败: orderNo={}, transactionId={}", outTradeNo, transactionId);
                    return false;
                }
            } else {
                // 课程订单支付处理
                updateResult = courseOrderService.updateWechatPayStatus(outTradeNo, (short) 1, (short) 2, payTime, transactionId);
                if (updateResult) {
                    log.info("课程订单微信支付成功，订单状态更新成功: orderNo={}, transactionId={}, payTime={}", 
                            outTradeNo, transactionId, payTime);
                    
                    // 处理课程班关联逻辑
                    handleCourseClassAssociation(outTradeNo);
                    
                    // 为用户创建课程学习记录
                    createUserCourseJoinRecord(outTradeNo);
                    
                } else {
                    log.error("课程订单状态更新失败: orderNo={}, transactionId={}", outTradeNo, transactionId);
                    return false;
                }
            }
            
            // 缓存支付状态到Redis
            cachePaymentStatus(outTradeNo, "SUCCESS", transactionId, payTime);
            
            log.info("微信支付通知处理成功: orderNo={}", outTradeNo);
            return true;
            
        } catch (Exception e) {
            log.error("处理微信支付通知失败", e);
            return false;
        }
    }
    
    /**
     * 判断订单类型
     * @param outTradeNo 订单号
     * @return true-考试订单，false-课程订单
     */
    private boolean isExamOrder(String outTradeNo) {
        if (outTradeNo == null || outTradeNo.trim().isEmpty()) {
            return false;
        }
        
        // EXAM开头的是考试订单
        if (outTradeNo.startsWith("EXAM")) {
            log.debug("识别为考试订单: {}", outTradeNo);
            return true;
        }
        
        // 纯数字的是课程订单
        if (outTradeNo.matches("\\d+")) {
            log.debug("识别为课程订单: {}", outTradeNo);
            return false;
        }
        
        // 其他格式默认按课程订单处理，但记录警告
        log.warn("未知订单号格式，默认按课程订单处理: {}", outTradeNo);
        return false;
    }
    
    /**
     * 解密微信支付回调资源数据
     */
    private String decryptResource(String ciphertext, String nonce, String associatedData) {
        try {
            // 获取API密钥
            String apiV3Key = wechatPayConfig.getApiV3Key();
            if (apiV3Key == null || apiV3Key.length() != 32) {
                log.error("API V3密钥长度不正确，应为32位: {}", apiV3Key != null ? apiV3Key.length() : "null");
                return null;
            }
            
            // Base64解码
            byte[] ciphertextBytes = Base64.getDecoder().decode(ciphertext);
            byte[] nonceBytes = nonce.getBytes(StandardCharsets.UTF_8);
            byte[] associatedDataBytes = associatedData != null ? associatedData.getBytes(StandardCharsets.UTF_8) : new byte[0];
            
            // 分离密文和认证标签
            int ciphertextLength = ciphertextBytes.length - 16; // GCM标签长度为16字节
            byte[] actualCiphertext = new byte[ciphertextLength];
            byte[] authTag = new byte[16];
            
            System.arraycopy(ciphertextBytes, 0, actualCiphertext, 0, ciphertextLength);
            System.arraycopy(ciphertextBytes, ciphertextLength, authTag, 0, 16);
            
            // 创建密钥规范
            SecretKeySpec keySpec = new SecretKeySpec(apiV3Key.getBytes(StandardCharsets.UTF_8), "AES");
            
            // 创建GCM参数规范
            GCMParameterSpec gcmSpec = new GCMParameterSpec(128, nonceBytes); // 128位标签长度
            
            // 创建Cipher并初始化
            Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
            cipher.init(Cipher.DECRYPT_MODE, keySpec, gcmSpec);
            
            // 设置关联数据
            if (associatedDataBytes.length > 0) {
                cipher.updateAAD(associatedDataBytes);
            }
            
            // 解密
            byte[] decryptedBytes = cipher.doFinal(ciphertextBytes);
            
            return new String(decryptedBytes, StandardCharsets.UTF_8);
            
        } catch (Exception e) {
            log.error("解密微信支付回调数据失败", e);
            return null;
        }
    }

    @Override
    public Result<?> queryPayment(String outTradeNo) {
        try {
            log.info("查询微信支付状态: outTradeNo={}", outTradeNo);
            
            // 构建查询URL
            String queryUrl = String.format("https://api.mch.weixin.qq.com/v3/pay/transactions/out-trade-no/%s?mchid=%s", 
                    outTradeNo, wechatPayConfig.getMchId());
            
            // 创建HTTP请求
            HttpGet httpGet = new HttpGet(queryUrl);
            httpGet.setHeader("Accept", "application/json");
            
            // 发送请求
            try (CloseableHttpResponse response = wechatPayClient.execute(httpGet)) {
                HttpEntity entity = response.getEntity();
                String responseBody = EntityUtils.toString(entity, "UTF-8");
                
                log.info("微信支付查询API响应: status={}, body={}", response.getStatusLine().getStatusCode(), responseBody);
                
                if (response.getStatusLine().getStatusCode() == 200) {
                    JSONObject responseJson = JSON.parseObject(responseBody);
                    
                    Map<String, Object> queryResult = new HashMap<>();
                    queryResult.put("outTradeNo", responseJson.getString("out_trade_no"));
                    queryResult.put("tradeState", responseJson.getString("trade_state"));
                    queryResult.put("tradeStateDesc", getTradeStateDesc(responseJson.getString("trade_state")));
                    queryResult.put("appId", responseJson.getString("appid"));
                    queryResult.put("mchId", responseJson.getString("mchid"));
                    queryResult.put("transactionId", responseJson.getString("transaction_id"));
                    
                    // 如果有金额信息
                    if (responseJson.containsKey("amount")) {
                        JSONObject amount = responseJson.getJSONObject("amount");
                        queryResult.put("total", amount.getInteger("total"));
                        queryResult.put("currency", amount.getString("currency"));
                    }
                    
                    log.info("微信支付状态查询成功: {}", queryResult);
                    return Result.success(queryResult);
                } else {
                    log.error("微信支付查询API调用失败: status={}, response={}", 
                            response.getStatusLine().getStatusCode(), responseBody);
                    return Result.fail("查询支付状态失败: " + responseBody);
                }
            }
        } catch (Exception e) {
            log.error("查询微信支付状态失败: outTradeNo={}", outTradeNo, e);
            return Result.fail("查询支付状态失败: " + e.getMessage());
        }
    }
    
    /**
     * 获取交易状态描述
     */
    private String getTradeStateDesc(String tradeState) {
        switch (tradeState) {
            case "SUCCESS":
                return "支付成功";
            case "REFUND":
                return "转入退款";
            case "NOTPAY":
                return "未支付";
            case "CLOSED":
                return "已关闭";
            case "REVOKED":
                return "已撤销";
            case "USERPAYING":
                return "用户支付中";
            case "PAYERROR":
                return "支付失败";
            default:
                return "未知状态";
        }
    }
    
    /**
     * 缓存支付状态到Redis
     */
    private void cachePaymentStatus(String orderNo, String status, String transactionId, LocalDateTime payTime) {
        try {
            Map<String, Object> paymentInfo = new HashMap<>();
            paymentInfo.put("orderNo", orderNo);
            paymentInfo.put("status", status);
            paymentInfo.put("transactionId", transactionId);
            // 将 LocalDateTime 转换为字符串格式，避免序列化问题
            paymentInfo.put("payTime", payTime != null ? payTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) : null);
            paymentInfo.put("payType", "wechat");
            paymentInfo.put("success", "SUCCESS".equals(status));
            paymentInfo.put("message", "SUCCESS".equals(status) ? "支付成功" : "支付失败");
            
            String redisKey = RedisConstants.PAYMENT_STATUS_PREFIX + orderNo;
            redisUtils.set(redisKey, paymentInfo, RedisConstants.PAYMENT_STATUS_EXPIRE);
            
            log.info("支付状态已缓存到Redis: orderNo={}, status={}", orderNo, status);
        } catch (Exception e) {
            log.error("缓存支付状态到Redis失败: orderNo={}", orderNo, e);
        }
    }
    
    /**
     * 处理课程班关联逻辑
     */
    private void handleCourseClassAssociation(String orderNo) {
        try {
            // 获取订单信息
            CourseOrder order = courseOrderService.getByOrderNo(orderNo);
            if (order == null) {
                log.warn("订单不存在，跳过课程班关联处理: orderNo={}", orderNo);
                return;
            }
            
            Long courseId = order.getCourseId();
            Long userId = order.getUserId();
            
            if (courseId == null || userId == null) {
                log.warn("订单信息不完整，跳过课程班关联处理: orderNo={}, courseId={}, userId={}", 
                        orderNo, courseId, userId);
                return;
            }
            
            // 检查是否已存在关联记录，避免重复插入
            CourseClassAssociation existingAssociation = courseClassAssociationService.getByMainAndDeputyCourseId(courseId, courseId);
            if (existingAssociation != null) {
                log.info("课程班关联已存在，跳过插入: orderNo={}, courseId={}", orderNo, courseId);
                return;
            }
            
            // 创建课程班关联记录
            CourseClassAssociation association = new CourseClassAssociation();
            association.setMainCourseId(courseId);
            association.setDeputyCourseId(courseId);
            association.setCreatedTime(LocalDateTime.now());
            association.setUpdatedTime(LocalDateTime.now());

            Result<?> save = courseClassAssociationService.save(association);
            if (save.getCode() == ResultCode.SUCCESS.getCode()) {
                log.info("课程班关联创建成功: orderNo={}, courseId={}, userId={}", orderNo, courseId, userId);
            } else {
                log.error("课程班关联创建失败: orderNo={}, courseId={}, userId={}", orderNo, courseId, userId);
            }
            
        } catch (Exception e) {
            log.error("处理课程班关联失败: orderNo={}", orderNo, e);
        }
    }
    
    /**
     * 为用户创建课程学习记录
     * @param orderNo 订单号
     */
    private void createUserCourseJoinRecord(String orderNo) {
        try {
            if (orderNo == null || orderNo.trim().isEmpty()) {
                log.warn("创建用户课程学习记录失败，订单号为空: orderNo={}", orderNo);
                return;
            }
            
            // 根据订单号查询订单信息
            CourseOrder order = courseOrderService.getByOrderNo(orderNo);
            if (order == null) {
                log.warn("创建用户课程学习记录失败，订单不存在: orderNo={}", orderNo);
                return;
            }
            
            Long userId = order.getUserId();
            Long courseId = order.getCourseId();
            
            if (userId == null || courseId == null) {
                log.warn("创建用户课程学习记录失败，用户ID或课程ID为空: userId={}, courseId={}", userId, courseId);
                return;
            }
            
            // 检查是否已存在该用户和课程的关联记录
            UserCourseJoin existingRecord = userCourseJoinMapper.selectOne(
                new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<UserCourseJoin>()
                    .eq(UserCourseJoin::getUserId, userId)
                    .eq(UserCourseJoin::getCourseId, courseId)
            );
            
            if (existingRecord != null) {
                log.info("用户课程学习记录已存在，跳过创建: userId={}, courseId={}", userId, courseId);
                return;
            }
            
            // 创建新的用户课程学习记录
            UserCourseJoin userCourseJoin = new UserCourseJoin();
            userCourseJoin.setUserId(userId);
            userCourseJoin.setCourseId(courseId);
            userCourseJoin.setLearnDuration(0); // 初始学习时长为0
            userCourseJoin.setProgress(0); // 初始进度为0%
            userCourseJoin.setStatus((short) 0); // 0-学习中
            userCourseJoin.setLastLearnTime(LocalDateTime.now());
            userCourseJoin.setCreatedTime(LocalDateTime.now());
            userCourseJoin.setUpdatedTime(LocalDateTime.now());
            
            int result = userCourseJoinMapper.insert(userCourseJoin);
            if (result > 0) {
                log.info("成功创建用户课程学习记录: userId={}, courseId={}, orderNo={}", userId, courseId, orderNo);
            } else {
                log.error("创建用户课程学习记录失败: userId={}, courseId={}, orderNo={}", userId, courseId, orderNo);
            }
        } catch (Exception e) {
            log.error("创建用户课程学习记录异常: orderNo={}", orderNo, e);
        }
    }
}
